#include "Corpse.h"
#include "Game.h"
#include "Player.h"
#include "ObjectDatabase.h"
#include "StringLib.h"
#include "Util.h"
#include "Renderer.h"
#include "GameState.h"

Corpse::Corpse(NpcType npcType) : Food(FT_CORPSE) {
	m_rotting = false;
	m_rotCounter = 100;
	m_npcType = npcType;
	const NpcInfo& info = g_objectDatabase->getNpcInfo(npcType);
	m_weight = info.corpseWeight;
	m_satiation = info.corpseSatiation;
	m_poisoned = info.corpsePoisoned;
}

Corpse::Corpse(std::ifstream& file) : Food(FT_CORPSE, file) {
	int* tokens = Util::intSplit(file);
	m_rotCounter = tokens[0];
	m_rotting = tokens[1] == 1;
	m_npcType = NpcType(tokens[2]);
	delete[] tokens;
	const NpcInfo& info = g_objectDatabase->getNpcInfo(m_npcType);
	m_weight = info.corpseWeight;
	m_satiation = info.corpseSatiation;
	m_poisoned = info.corpsePoisoned;
	g_gameState->addCorpse(this);
}

Corpse::~Corpse() {
}

void Corpse::save(std::ofstream& file) const {
	file << getType(TH_GENERIC_TYPE) << " " << "1" << "\n";
	Item::save(file);
	file << m_rotCounter << " " << (m_rotting ? 1 : 0) << " " << m_npcType << "\n";
}

std::string Corpse::getItemName(int mod) const {
	int numStacked = m_numStacked - mod;
	std::string output = "";
	if(m_statusIdentified)
		output += g_stringLib->getMiscString(MST_STATUS, m_status) + " ";
	output += g_stringLib->getObjectString(TH_NPC_TYPE, m_npcType) + " " + (numStacked > 1 ? getPluralName() : getBasicName());
	if(m_rotting)
		output += " (rotting)";
	if(numStacked > 1)
		output = Util::intToString(numStacked) + " " + output;
	return output;
}

int Corpse::getSatiation() const {
	if(m_poisoned)
		return 0;
	return Food::getSatiation();
}

void Corpse::eatEffects(Player* player) {
	if(m_poisoned)
		player->addStatusEffect(SE_POISON, 100);
	/*switch(m_npcType) {
	case NT_DRAGON:
		if(player->getStr() < 16)
			player->changeStat(STR, 1);
		break;
	case NT_ORC:
		if(player->getVit() < 12)
			player->changeStat(VIT, 1);
		break;
	}*/
}

void Corpse::render(float x, float y) {
	g_renderer->render(*this, x, y);
}

bool Corpse::typeEqual(const GameObject& obj) const {
	 return GameObject::typeEqual(obj) && m_npcType == ((const Corpse&)obj).getNpcType();
}

bool Corpse::reduceRotCounter() {
	m_rotCounter -= 5;
	if(m_rotCounter < 25) {
		if(!m_rotting && m_parentList == g_player->getInventory())
			g_textLog->addLine(g_stringLib->getTextString(ST_PLAYER_ROTTING));
		m_rotting = true;
	}
	if(m_rotCounter <= 0) {
		if(m_parentList == g_player->getInventory()) {
			g_player->forceRemoveItemFromInventory(this);
			g_textLog->addLine(g_stringLib->getTextString(ST_PLAYER_ROTTED));
		}
		return true;
	}
	return false;
}

void Corpse::addToStack(Item* item) {
	Item::addToStack(item);
	m_rotCounter = (m_rotCounter+((Corpse*)item)->getRotCounter()) / 2;
}

void Corpse::reduceStackCount(int num, bool destroy, std::list<Item*>* items) {
	if(m_numStacked - num <= 0 && destroy)
		g_gameState->removeCorpse(this);
	Item::reduceStackCount(num, destroy, items);
}
